#include "ObjectArray.h"

#include <stdio.h>
#include <stdlib.h>

struct _ObjectArray
{
	EventObject    parent_instance;
	ObjectSortFunc sort_func;
	/* 数组表 */
	epointer *array;
	/* 插入表的对象数量 */
	euint32 object_number;
	/* 当前插入的序号 */
	euint32 insert_index;
	/* 当前迭代序号 */
	euint32 iteration_index;
	/* 对象的析构方法 */
	void (*object_finalize)(epointer);
	/* 排序是否是由小到大的正序 */
	bool is_positive_sequence;
};

static void
object_array_finalize(ObjectArray *self)
{
	if (!self->array)
		return;
	if (self->object_finalize)
		for (int i = 0; i < self->insert_index; ++i)
			self->object_finalize(self->array[i]);
	free(self->array);
}

ObjectArray *
object_array_new(euint32 object_number)
{
	ObjectArray *object = MALLOC_NEW(ObjectArray);

	event_object_init(EVENT_OBJECT(object));
	event_object_set_finalize(object, FINALIZE(object_array_finalize));

	object->sort_func	= NULL;
	object->object_number	= object_number;
	object->insert_index	= 0;
	object->object_finalize = NULL;
	object->array		= NULL;
	object->iteration_index = 0;
	//
	object->is_positive_sequence = true;

	return object;
}

void
object_array_set_sort_function(ObjectArray *self, ObjectSortFunc func)
{
	return_if_fail(self != NULL, object_array_set_sort_function);
	self->sort_func = func;
}

void
object_array_set_is_positive_sequence(ObjectArray *self,
				      bool	   is_positive_sequence)
{
	return_if_fail(self != NULL, object_array_set_is_positive_sequence);
	self->is_positive_sequence = is_positive_sequence;
}

void
object_array_set_object_finalize(ObjectArray *self, void (*finalize)(epointer))
{
	return_if_fail(self != NULL, object_array_set_object_finalize);
	self->object_finalize = finalize;
}

epointer
object_array_get_with_index(ObjectArray *self, euint32 index)
{
	return_val_if_fail(self != NULL, object_array_get_with_index, NULL);
	if (index >= self->insert_index)
		return NULL;
	return self->array[index];
}

void
object_array_insert_object(ObjectArray *self, epointer any_object)
{
	return_if_fail(self != NULL, object_array_insert_object);
	if (self->insert_index == self->object_number) {
		self->object_number += 1;
		self->array	     = self->array ? realloc(self->array,
							     (sizeof(epointer) *
						      self->object_number)) :
						     malloc(sizeof(epointer));
	} else if (!self->array) {
		self->array = malloc(sizeof(epointer) * self->object_number);
	}
	self->array[self->insert_index++] = any_object;
}

void
object_array_remove_object(ObjectArray *self, epointer any_object)
{
	epointer *slot = NULL;
	euint32	  index;
	bool	  is_founded = false;
	return_if_fail(self != NULL, object_array_remove_object);
	if (!self->array || self->insert_index == 0)
		return;
	slot = self->array;
	for (index = 0; index < self->insert_index; ++index, ++slot) {
		if (*slot == any_object) {
			is_founded = true;
			break;
		}
	}
	if (!is_founded)
		return;
	if (self->object_finalize)
		self->object_finalize(*slot);
	*slot = NULL;
	for (; index < self->insert_index; ++index, ++slot)
		*slot = *(slot + 1);
	self->insert_index -= 1;
}

void
object_array_sort(ObjectArray *self)
{
	epointer tmp;
	bool	 sort_flag = true;
	return_if_fail(self != NULL, object_array_sort);
	if (!self->sort_func)
		return;
	if (self->insert_index < 2)
		return;
	while (sort_flag) {
		for (int i = 0; i < self->insert_index - 1; ++i) {
			if (self->is_positive_sequence ==
			    self->sort_func(self->array[i],
					    self->array[i + 1])) {
				tmp		   = self->array[i];
				self->array[i]	   = self->array[i + 1];
				self->array[i + 1] = tmp;
				sort_flag	   = false;
			}
		}
		sort_flag = !sort_flag;
	}
}

void
object_array_iteration_reset(ObjectArray *self)
{
	return_if_fail(self != NULL, object_array_iteration_reset);
	self->iteration_index = 0;
}

epointer
object_array_iteration_get(ObjectArray *self)
{
	return_val_if_fail(self != NULL, object_array_iteration_get, NULL);
	if (!self->array || self->iteration_index >= self->insert_index)
		return NULL;
	return self->array[self->iteration_index++];
}
